<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Leaflet</title>
    <link rel="stylesheet" href="leaflet.css" />
    <script src="leaflet.js"></script>
    <!--叶片状蚂蚁路径-->
    <script src="plugins/leaflet-ant-path.js"></script>
    <!--方向插件-->
    <script src="plugins/leaflet.rotatedMarker.js"></script>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      #search {
        height: 60px;
        width: 100%;
        position: fixed;
        top: 0;
        left: 0;
        background: #000000;
        z-index: 10000000;
      }

      #search-btn,
      #stop-btn {
        cursor: pointer;
      }

      #map {
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="search">
      <input id="search-input" />
      <button id="search-btn">搜索</button>
      <button id="stop-btn">停止</button>
    </div>
    <div id="map"></div>

    <script>
      class AntPathPolyline {
        static polylineStyleConfig = [
          {
            color: "#006600",
            fillColor: "#006600",
            pulseColor: "#e5ffe5"
          },
          {
            color: "#0000cc",
            fillColor: "#0000cc",
            pulseColor: "#ccccff"
          },
          {
            color: "#e62f00",
            fillColor: "#e62f00",
            pulseColor: "#ffc2b3"
          },
          {
            color: "#8600b3",
            fillColor: "#8600b3",
            pulseColor: "#ecb3ff"
          },
          {
            color: "#b35900",
            fillColor: "#b35900",
            pulseColor: "#ffd9b3"
          },
          {
            color: "#ff9900",
            fillColor: "#ff9900",
            pulseColor: "#ffe0b3"
          },
          {
            color: "#00b2b3",
            fillColor: "#00b2b3",
            pulseColor: "#b3ffff"
          },
          {
            color: "#000000",
            fillColor: "#000000",
            pulseColor: "#FFFFFF"
          },
          {
            color: "#006699",
            fillColor: "#006699",
            pulseColor: "#b3e6ff"
          },
          {
            color: "#cc0099",
            fillColor: "#cc0099",
            pulseColor: "#ffb3ec"
          }
        ];

        static carIconConfig = [
          "./icons/car0.png",
          "./icons/car1.png",
          "./icons/car2.png",
          "./icons/car3.png",
          "./icons/car4.png",
          "./icons/car5.png",
          "./icons/car6.png",
          "./icons/car7.png",
          "./icons/car8.png",
          "./icons/car9.png"
        ];

        static positionIconConfig = "./icons/nav.svg";

        static layerGroups = {};

        // 获取当前位置方向
        static calculateBearing(lat1, lon1, lat2, lon2) {
          const dLon = (lon2 - lon1) * (Math.PI / 180);
          const y = Math.sin(dLon) * Math.cos(lat2 * (Math.PI / 180));
          const x =
            Math.cos(lat1 * (Math.PI / 180)) *
              Math.sin(lat2 * (Math.PI / 180)) -
            Math.sin(lat1 * (Math.PI / 180)) *
              Math.cos(lat2 * (Math.PI / 180)) *
              Math.cos(dLon);
          let bearing = Math.atan2(y, x) * (180 / Math.PI);

          // 将方位角规范化为0到360度之间
          if (bearing < 0) {
            bearing = (bearing + 360) % 360;
          }

          return bearing;
        }

        // 生成随机字符串
        static generateUniqueChar() {
          // 获取当前时间戳，确保每次调用都是唯一的
          const timestamp = new Date().getTime().toString(36);
          // 生成一个随机数，并转换为36进制字符串
          const randomValue = Math.random()
            .toString(36)
            .substr(2, 9);
          // 返回时间戳和随机数的组合，确保唯一性
          return timestamp + randomValue;
        }

        drawPolyline(
          map,
          points,
          width,
          polylineStyle,
          carIcon,
          layerGroupName
        ) {
          if (points.length === 0) {
            return;
          }

          if (AntPathPolyline.layerGroups[layerGroupName]) {
            map.removeLayer(AntPathPolyline.layerGroups[layerGroupName]);
            AntPathPolyline.layerGroups[layerGroupName] = L.layerGroup().addTo(
              map
            );
          } else {
            AntPathPolyline.layerGroups[layerGroupName] = L.layerGroup().addTo(
              map
            );
          }

          // 起始点
          const marker = L.marker(points[0], {
            icon: L.icon({
              iconUrl: AntPathPolyline.positionIconConfig, // 图标图片的URL
              iconSize: [32, 32], // 图标的大小
              iconAnchor: [15, 15], // 图标的锚点，即图标的位置应该放置在地图上的位置
              popupAnchor: [-3, -76] // 弹出框的锚点，即当你点击图标时，弹出框应该出现在哪个位置
            })
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 线
          L.polyline
            .antPath(points, {
              ...polylineStyle,
              opacity: 6,
              delay: 10000,
              dashArray: [5, 30]
            })
            .addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 最新的点
          L.marker(points[points.length - 1], {
            icon: L.icon({
              iconUrl: carIcon,
              iconSize: [30, 30], // icon的大小
              iconAnchor: [16, 15], // icon的渲染的位置（相对与marker）
              shadowAnchor: [0, 0], // shadow的渲染的位置（相对于marker）
              popupAnchor: [0, 0] //若是绑定了popup的popup的打开位置（相对于icon）
            }),
            title: "test",
            draggable: true,
            rotationAngle:
              points.length > 1
                ? AntPathPolyline.calculateBearing(
                    points[points.length - 2][0],
                    points[points.length - 2][1],
                    points[points.length - 1][0],
                    points[points.length - 1][1]
                  )
                : 0
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          const circle = L.circle(points[points.length - 1], {
            stroke: true,
            dashArray: "4",
            color: "red",
            fillColor: "#f03",
            fillOpacity: 0.2,
            weight: 2,
            radius: 1200 * width
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          circle.on("mouseover", e => {
            alert("半径为0.5km.");
          });
        }
      }

      const map = L.map("map").setView([28.23, 112.93], 13);

      L.tileLayer(
        "http://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
        {
          minZoom: 11,
          maxZoom: 16
          // attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }
      ).addTo(map);

      let width = 0.25;
      let timers = [];
      let points = {};

      document.getElementById("search-btn").onclick = function() {
        const allLayers = map._layers; // 注意：_layers是一个内部属性，可能在未来版本中改变

        // 遍历所有图层，并检查它们是否是L.layerGroup的实例
        for (const layerId in allLayers) {
          const layer = allLayers[layerId];

          // 检查图层是否是L.layerGroup的实例
          if (layer instanceof L.LayerGroup) {
            // 如果是，则从地图上移除它
            map.removeLayer(layer);
          }

          // 注意：对于嵌套的layerGroup（即layerGroup中包含其他layerGroup），
          // 你可能需要递归地处理它们，但上面的代码只处理了一级layerGroup。
        }

        if (timers.length > 0) {
          for (let i = 0; i < timers.length; i++) {
            clearInterval(timers[i]);
          }
        }

        timers = [];
        points = {};

        const polylineArr = ["a", "b", "c", "d", "e"];

        for (let i = 0; i < polylineArr.length; i++) {
          const antPathPolylineObj = new AntPathPolyline();
          const antPathPolylineName = AntPathPolyline.generateUniqueChar();
          points["data" + i] = [];

          const timer = setInterval(function() {
            points["data" + i].push([
              28.23 + ((1 + i) * Math.random()) / 20,
              112.93 + ((1 + i) * Math.random()) / 20
            ]);
            antPathPolylineObj.drawPolyline(
              map,
              points["data" + i],
              width,
              AntPathPolyline.polylineStyleConfig[i],
              AntPathPolyline.carIconConfig[i],
              antPathPolylineName
            );
          }, 1000);

          timers.push(timer);
        }
      };

      document.getElementById("stop-btn").onclick = function() {
        if (timers.length > 0) {
          for (let i = 0; i < timers.length; i++) {
            clearInterval(timers[i]);
          }
        }
      };
    </script>
  </body>
</html>
